package com.coursebooking.controller;

import com.coursebooking.model.Booking;
import com.coursebooking.model.Course;
import com.coursebooking.model.Student;
import com.coursebooking.service.BookingService;
import com.coursebooking.service.CourseService;
import com.coursebooking.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/bookings")
@CrossOrigin(origins = "*")
public class BookingController {

    @Autowired
    private BookingService bookingService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private CourseService courseService;

    @GetMapping
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<List<Booking>> getAllBookings() {
        List<Booking> bookings = bookingService.findAll();
        return ResponseEntity.ok(bookings);
    }

    @GetMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER') or hasRole('STUDENT')")
    public ResponseEntity<Booking> getBookingById(@PathVariable Long id) {
        Optional<Booking> booking = bookingService.findById(id);
        return booking.map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build());
    }

    @PostMapping
    @PreAuthorize("hasRole('STUDENT')")
    public ResponseEntity<?> createBooking(@RequestBody BookingRequest bookingRequest) {
        try {
            Booking booking = bookingService.createBooking(
                    bookingRequest.getStudentId(),
                    bookingRequest.getCourseId()
            );
            return ResponseEntity.ok(booking);
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(new MessageResponse(e.getMessage()));
        }
    }

    @PutMapping("/{id}/status")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseEntity<?> updateBookingStatus(@PathVariable Long id, @RequestBody StatusRequest statusRequest) {
        try {
            Booking.BookingStatus status = Booking.BookingStatus.valueOf(statusRequest.getStatus().toUpperCase());
            Booking booking = bookingService.updateBookingStatus(id, status);
            return ResponseEntity.ok(booking);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().body(new MessageResponse("无效的状态"));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(new MessageResponse("更新状态失败: " + e.getMessage()));
        }
    }

    @PutMapping("/{id}/cancel")
    @PreAuthorize("hasRole('STUDENT') or hasRole('ADMIN')")
    public ResponseEntity<?> cancelBooking(@PathVariable Long id) {
        try {
            bookingService.cancelBooking(id);
            return ResponseEntity.ok(new MessageResponse("预约已取消"));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(new MessageResponse("取消预约失败: " + e.getMessage()));
        }
    }

    @DeleteMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<?> deleteBooking(@PathVariable Long id) {
        try {
            bookingService.deleteBooking(id);
            return ResponseEntity.ok(new MessageResponse("预约删除成功"));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(new MessageResponse("删除预约失败: " + e.getMessage()));
        }
    }

    @GetMapping("/student/{studentId}")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER') or hasRole('STUDENT')")
    public ResponseEntity<List<Booking>> getBookingsByStudent(@PathVariable Long studentId) {
        Optional<Student> studentOpt = studentService.findById(studentId);
        if (!studentOpt.isPresent()) {
            return ResponseEntity.notFound().build();
        }
        List<Booking> bookings = bookingService.findByStudent(studentOpt.get());
        return ResponseEntity.ok(bookings);
    }

    @GetMapping("/course/{courseId}")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseEntity<List<Booking>> getBookingsByCourse(@PathVariable Long courseId) {
        Optional<Course> courseOpt = courseService.findById(courseId);
        if (!courseOpt.isPresent()) {
            return ResponseEntity.notFound().build();
        }
        List<Booking> bookings = bookingService.findByCourse(courseOpt.get());
        return ResponseEntity.ok(bookings);
    }

    @GetMapping("/status/{status}")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseEntity<List<Booking>> getBookingsByStatus(@PathVariable String status) {
        try {
            Booking.BookingStatus bookingStatus = Booking.BookingStatus.valueOf(status.toUpperCase());
            List<Booking> bookings = bookingService.findByStatus(bookingStatus);
            return ResponseEntity.ok(bookings);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().build();
        }
    }

    @GetMapping("/course/{courseId}/count")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseEntity<?> getConfirmedBookingsCount(@PathVariable Long courseId) {
        Optional<Course> courseOpt = courseService.findById(courseId);
        if (!courseOpt.isPresent()) {
            return ResponseEntity.notFound().build();
        }
        long count = bookingService.getConfirmedBookingsCount(courseOpt.get());
        return ResponseEntity.ok(new CountResponse(count));
    }

    @GetMapping("/check")
    @PreAuthorize("hasRole('STUDENT')")
    public ResponseEntity<?> checkBookingExists(@RequestParam Long studentId, @RequestParam Long courseId) {
        Optional<Student> studentOpt = studentService.findById(studentId);
        Optional<Course> courseOpt = courseService.findById(courseId);
        
        if (!studentOpt.isPresent() || !courseOpt.isPresent()) {
            return ResponseEntity.notFound().build();
        }
        
        boolean exists = bookingService.existsByStudentAndCourse(studentOpt.get(), courseOpt.get());
        return ResponseEntity.ok(new ExistsResponse(exists));
    }

    // 内部类定义
    public static class BookingRequest {
        private Long studentId;
        private Long courseId;

        public Long getStudentId() { return studentId; }
        public void setStudentId(Long studentId) { this.studentId = studentId; }
        public Long getCourseId() { return courseId; }
        public void setCourseId(Long courseId) { this.courseId = courseId; }
    }

    public static class StatusRequest {
        private String status;

        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }
    }

    public static class MessageResponse {
        private String message;

        public MessageResponse(String message) {
            this.message = message;
        }

        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
    }

    public static class CountResponse {
        private long count;

        public CountResponse(long count) {
            this.count = count;
        }

        public long getCount() { return count; }
        public void setCount(long count) { this.count = count; }
    }

    public static class ExistsResponse {
        private boolean exists;

        public ExistsResponse(boolean exists) {
            this.exists = exists;
        }

        public boolean isExists() { return exists; }
        public void setExists(boolean exists) { this.exists = exists; }
    }
}